/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.service.evaluation;

import cn.ac.nercis.pes.model.bo.excel.AssetExcelBO;
import cn.ac.nercis.pes.model.bo.excel.asset.*;
import cn.ac.nercis.pes.common.constant.common.AssetConstants;
import cn.ac.nercis.pes.common.constant.common.BaseConstants;
import cn.ac.nercis.pes.common.constant.evaluation.EvaluationModule;
import cn.ac.nercis.pes.common.constant.excel.AssetExcelSheet;
import cn.ac.nercis.pes.common.constant.knowledge.AssetClassification;
import cn.ac.nercis.pes.common.constant.project.FinishState;
import cn.ac.nercis.pes.common.constant.project.SystemState;
import cn.ac.nercis.pes.common.constant.rules.KeyDataReqTargetRule;
import cn.ac.nercis.pes.common.constant.rules.PhySecurityReqTargetRule;
import cn.ac.nercis.pes.common.constant.rules.SubBusinessReqTargetRule;
import cn.ac.nercis.pes.model.dto.common.Result;
import cn.ac.nercis.pes.model.dto.common.ResultCode;
import cn.ac.nercis.pes.model.dto.evaluation.asset.*;
import cn.ac.nercis.pes.model.dto.evaluation.prepare.PersonnelDTO;
import cn.ac.nercis.pes.model.dto.evaluation.prepare.SecurityDocumentDTO;
import cn.ac.nercis.pes.model.dto.project.SystemProcessDTO;
import cn.ac.nercis.pes.repository.dal.evaluation.AssetRepository;
import cn.ac.nercis.pes.repository.mapper.evaluation.AssetImportMapper;
import cn.ac.nercis.pes.repository.mapper.evaluation.AssetMapper;
import cn.ac.nercis.pes.service.project.SystemProcessService;
import cn.ac.nercis.pes.service.utils.AssetUtils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 系统资产导入服务类
 * @author zpy
 * @version 1.0.0
 */
@Slf4j
@Service
public class AssetImportService {
    private static final Integer HEAD_ROW_NUMBER = 3;
    private static final Integer MANAGE_HEAD_ROW_NUMBER = 2;
    private static final String REQUIRED_EMPTY_ERROR = "必填信息不能为空";
    private final AssetRepository assetRepository;
    private final AssetService assetService;
    private final SecurityDocumentService securityDocumentService;
    private final PersonnelService personnelService;
    private final SystemProcessService processService;

    @Autowired
    public AssetImportService(AssetRepository assetRepository,AssetService assetService,
                              SecurityDocumentService securityDocumentService,PersonnelService personnelService,
                              SystemProcessService processService) {
        this.assetRepository = assetRepository;
        this.assetService = assetService;
        this.securityDocumentService = securityDocumentService;
        this.personnelService = personnelService;
        this.processService = processService;
    }

    public Result<AssetExcelBO> checkImportData(@NonNull File excelFile){
        try {
            AssetExcelBO excelData = AssetExcelBO.builder()
                    .phyEnvs(readPhyEnvAssets(excelFile))
                    .phySecurity(readPhySecurityAssets(excelFile))
                    .pwdProducts(readPwdProductAssets(excelFile))
                    .serverStorages(readServerStorageAssets(excelFile))
                    .networkSecurity(readNetworkSecurityAssets(excelFile))
                    .databases(readDatabaseAssets(excelFile))
                    .keyBusiness(readKeyBusinessAssets(excelFile))
                    .subBusiness(readSubBusinessAssets(excelFile))
                    .keyData(readKeyDataAssets(excelFile))
                    .securityDocuments(readSecurityDocumentAssets(excelFile))
                    .personnel(readPersonnelAssets(excelFile))
                    .build();
            this.checkRelatedData(excelData);
            return Result.success(excelData);
        }catch (Exception ex){
            log.error("读取导入的系统资产文件失败：",ex);
            return Result.failed("读取系统资产失败");
        }
    }

    public Result<AssetExcelBO> importAssetData(@NonNull String systemId, @NonNull AssetExcelBO excelData){
        try{
            return Result.success(AssetExcelBO.builder()
                    .phyEnvs(importPhyEnvAssets(systemId,excelData))
                    .phySecurity(importPhySecurityAssets(systemId,excelData))
                    .pwdProducts(importPwdProductAssets(systemId,excelData))
                    .serverStorages(importServerStorageAssets(systemId,excelData))
                    .networkSecurity(importNetworkSecurityAssets(systemId,excelData))
                    .databases(importDatabaseAssets(systemId,excelData))
                    .keyBusiness(importKeyBusinessAssets(systemId,excelData))
                    .subBusiness(importSubBusinessAssets(systemId,excelData))
                    .keyData(importKeyDataAssets(systemId,excelData))
                    .securityDocuments(importSecurityDocument(systemId,excelData))
                    .personnel(importPersonnel(systemId,excelData))
                    .build());
        }catch (Exception ex){
            log.error("系统资产对象导入失败，",ex);
            return Result.failed(ResultCode.ASSET_IMPORT_FAIL);
        }
    }

    public Result<String> coverAssetData(@NonNull String systemId,@NonNull AssetExcelBO excelData){
        try{
            coverPhyEnvAssets(systemId,excelData);
            coverPhySecurityAsset(systemId,excelData);
            coverPwdProductAsset(systemId,excelData);
            coverServerStorageAsset(systemId,excelData);
            coverNetworkSecurityAsset(systemId,excelData);
            coverDatabaseAsset(systemId,excelData);
            coverKeyBusinessAsset(systemId,excelData);
            coverSubBusinessAsset(systemId,excelData);
            coverKeyDataAsset(systemId,excelData);
            coverSecurityDocument(systemId,excelData);
            coverPersonnel(systemId,excelData);
            return Result.success();
        }catch (Exception ex){
            log.error("系统资产对象导入覆盖原有资产对象失败，",ex);
            return Result.failed(ResultCode.ASSET_IMPORT_COVER_FAIL);
        }
    }

    private void checkRelatedData(AssetExcelBO excelBO){
        excelBO.getPhySecurity()
                .stream()
                .filter(BaseExcelBO::getResult)
                .forEach(ps->{
                    boolean notExist = excelBO.getPhyEnvs()
                            .stream()
                            .noneMatch(pe-> StringUtils.equals(pe.getName(),ps.getLocation()));
                    if(notExist){
                        ps.setResult(false);
                        ps.setValidMsg("所在物理环境名不存在");
                    }
                });
        excelBO.getPhySecurity()
                .stream()
                .filter(PhySecurityBO::getResult)
                .forEach(sb-> Stream.of(StringUtils.split(sb.getRequire(), AssetConstants.KEY_DATA_REQ_SPLIT))
                        .filter(StringUtils::isNotBlank)
                        .forEach(r->{
                            if(Objects.isNull(PhySecurityReqTargetRule.fromName(r))){
                                sb.setResult(false);
                                sb.setValidMsg(String.format("安全需求：%s无效，请检查录入的格式是否正确",r));
                            }
                        }));
        excelBO.getDatabases()
                .stream()
                .filter(DatabaseBO::getResult)
                .forEach(db->{
                    for(String location:StringUtils.split(db.getLocation(),AssetConstants.KEY_BUSINESS_LOCATION_SPLIT)){
                        boolean notExist = excelBO.getServerStorages()
                                .stream()
                                .noneMatch(pe-> StringUtils.equals(pe.getName(),location));
                        if(notExist){
                            db.setResult(false);
                            db.setValidMsg(String.format("部署位置(%s)不存在",location));
                            break;
                        }
                    }
                });
        excelBO.getKeyBusiness()
                .stream()
                .filter(BaseExcelBO::getResult)
                .forEach(kb->{
                    for(String location:StringUtils.split(kb.getLocation(),AssetConstants.KEY_BUSINESS_LOCATION_SPLIT)){
                        boolean notExist = excelBO.getServerStorages()
                                .stream()
                                .noneMatch(pe-> StringUtils.equals(pe.getName(),location));
                        if(notExist){
                            kb.setResult(false);
                            kb.setValidMsg(String.format("部署位置(%s)不存在",location));
                            break;
                        }
                    }
                });
        excelBO.getSubBusiness()
                .stream()
                .filter(SubBusinessBO::getResult)
                .forEach(sb->{
                    boolean notExist = excelBO.getKeyBusiness()
                            .stream()
                            .noneMatch(kb-> StringUtils.equals(kb.getName(),sb.getOwnedApp()));
                    if(notExist){
                        sb.setResult(false);
                        sb.setValidMsg("所属应用不存在");
                    }
                });
        excelBO.getSubBusiness()
                .stream()
                .filter(SubBusinessBO::getResult)
                .forEach(sb-> Stream.of(StringUtils.split(sb.getRequire(), AssetConstants.KEY_DATA_REQ_SPLIT))
                        .filter(StringUtils::isNotBlank)
                        .forEach(r->{
                            if(Objects.isNull(SubBusinessReqTargetRule.fromName(r))){
                                sb.setResult(false);
                                sb.setValidMsg(String.format("安全需求：%s无效，请检查录入的格式是否正确",r));
                            }
                        }));
        excelBO.getKeyData()
                .stream()
                .filter(BaseExcelBO::getResult)
                .forEach(kd->{
                    boolean notExist = excelBO.getKeyBusiness()
                            .stream()
                            .noneMatch(kb-> StringUtils.equals(kb.getName(),kd.getOwnedApp()));
                    if(notExist){
                        kd.setResult(false);
                        kd.setValidMsg("所属应用不存在");
                    }
                });
        excelBO.getKeyData()
                .stream()
                .filter(kd->kd.getResult() && StringUtils.isNotBlank(kd.getLocation()))
                .forEach(kd-> {
                    boolean notExist = excelBO.getDatabases()
                            .stream()
                            .noneMatch(db -> StringUtils.equals(db.getName(), kd.getLocation()));
                    if (notExist) {
                        notExist = excelBO.getServerStorages()
                                .stream()
                                .noneMatch(ss -> StringUtils.equals(ss.getName(), kd.getLocation()));
                    }
                    if (notExist) {
                        kd.setResult(false);
                        kd.setValidMsg("存储位置不存在");
                    }
                });
        excelBO.getKeyData()
                .stream()
                .filter(KeyDataBO::getResult)
                .forEach(kd-> Stream.of(StringUtils.split(kd.getRequire(), AssetConstants.KEY_DATA_REQ_SPLIT))
                        .filter(StringUtils::isNotBlank)
                        .forEach(r->{
                            if(Objects.isNull(KeyDataReqTargetRule.fromName(r))){
                                kd.setResult(false);
                                kd.setValidMsg(String.format("安全需求：%s无效，请检查录入的格式是否正确",r));
                            }
                        }));
    }

    private List<PhyEnvBO> readPhyEnvAssets(@NonNull File excelFile){
        List<PhyEnvBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,PhyEnvBO.class, new AnalysisEventListener<PhyEnvBO>() {
            @Override
            public void invoke(PhyEnvBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.PHY_ENV.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<PhySecurityBO> readPhySecurityAssets(@NonNull File excelFile){
        List<PhySecurityBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,PhySecurityBO.class, new AnalysisEventListener<PhySecurityBO>() {
            @Override
            public void invoke(PhySecurityBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.PHY_SECURITY.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<PwdProductBO> readPwdProductAssets(@NonNull File excelFile){
        List<PwdProductBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,PwdProductBO.class, new AnalysisEventListener<PwdProductBO>() {
            @Override
            public void invoke(PwdProductBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.PWD_PRODUCT.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<ServerStorageBO> readServerStorageAssets(@NonNull File excelFile){
        List<ServerStorageBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,ServerStorageBO.class, new AnalysisEventListener<ServerStorageBO>() {
            @Override
            public void invoke(ServerStorageBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.SERVER_STORAGE.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<NetworkSecurityBO> readNetworkSecurityAssets(@NonNull File excelFile){
        List<NetworkSecurityBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,NetworkSecurityBO.class, new AnalysisEventListener<NetworkSecurityBO>() {
            @Override
            public void invoke(NetworkSecurityBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.NETWORK_SECURITY.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<DatabaseBO> readDatabaseAssets(@NonNull File excelFile){
        List<DatabaseBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,DatabaseBO.class, new AnalysisEventListener<DatabaseBO>() {
            @Override
            public void invoke(DatabaseBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.DATABASE.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<KeyBusinessBO> readKeyBusinessAssets(@NonNull File excelFile){
        List<KeyBusinessBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,KeyBusinessBO.class, new AnalysisEventListener<KeyBusinessBO>() {
            @Override
            public void invoke(KeyBusinessBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.KEY_BUSINESS.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<SubBusinessBO> readSubBusinessAssets(@NonNull File excelFile){
        List<SubBusinessBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,SubBusinessBO.class, new AnalysisEventListener<SubBusinessBO>() {
            @Override
            public void invoke(SubBusinessBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.SUB_BUSINESS.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<KeyDataBO> readKeyDataAssets(@NonNull File excelFile){
        List<KeyDataBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,KeyDataBO.class, new AnalysisEventListener<KeyDataBO>() {
            @Override
            public void invoke(KeyDataBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.KEY_DATA.getName()).headRowNumber(HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            a.setRequire(AssetUtils.getKeyDataReq(a.getRequire()));
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<SecurityDocumentBO> readSecurityDocumentAssets(@NonNull File excelFile){
        List<SecurityDocumentBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(MANAGE_HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,SecurityDocumentBO.class, new AnalysisEventListener<SecurityDocumentBO>() {
            @Override
            public void invoke(SecurityDocumentBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.SECURITY_DOC.getName()).headRowNumber(MANAGE_HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<PersonnelBO> readPersonnelAssets(@NonNull File excelFile){
        List<PersonnelBO> assets = new ArrayList<>();
        AtomicInteger rowNumber = new AtomicInteger(MANAGE_HEAD_ROW_NUMBER+1);
        EasyExcel.read(excelFile,PersonnelBO.class, new AnalysisEventListener<PersonnelBO>() {
            @Override
            public void invoke(PersonnelBO data, AnalysisContext analysisContext) {
                if(Objects.nonNull(data) && !data.isEmpty()){
                    data.setRowNumber(rowNumber.getAndIncrement());
                    assets.add(data);
                }else{
                    rowNumber.getAndIncrement();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet(AssetExcelSheet.PERSONNEL.getName()).headRowNumber(MANAGE_HEAD_ROW_NUMBER).doRead();
        assets.forEach(a->{
            a.setResult(a.validRequired());
            if(!a.getResult()){
                a.setValidMsg(REQUIRED_EMPTY_ERROR);
            }
        });
        return assets;
    }

    private List<PhyEnvBO> importPhyEnvAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPhyEnvs())){
            return Collections.emptyList();
        }
        List<PhyEnvDTO> assetList = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.PHY_ENV.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toPhyEnvDTO)
                .toList();
        List<PhyEnvBO> repeatAsset = new ArrayList<>();
        excelData.getPhyEnvs().forEach(asset->{
            Optional<PhyEnvDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                Result<String> result =  assetService.savePhyEnv(systemId, AssetImportMapper.INSTANCE.toDTO(asset));
                if(!result.isSuccess()){
                    log.warn("导入的物理环境资产信息：{}，保存失败",asset);
                }else{
                    processService.setSystemProcess(SystemProcessDTO.builder()
                            .systemId(systemId)
                            .state(SystemState.PREPARE)
                            .name(EvaluationModule.ASSET_PHY_ENV.getName())
                            .finishState(FinishState.FINISH)
                            .build());
                }
            }
        });
        return repeatAsset;
    }

    private List<PhySecurityBO> importPhySecurityAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPhySecurity())){
            return Collections.emptyList();
        }
        List<PhyEnvDTO> phyEnvAssets = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.PHY_ENV.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toPhyEnvDTO)
                .collect(Collectors.toList());

        List<PhySecurityDTO> assetList = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.PHY_SECURITY.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toPhySecurity)
                .collect(Collectors.toList());
        List<PhySecurityBO> repeatAsset = new ArrayList<>();
        excelData.getPhySecurity().forEach(asset->{
            Optional<PhySecurityDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                if(StringUtils.isBlank(asset.getIsUse())){
                    asset.setIsUse(AssetConstants.USE_TAG);
                }
                savePhySecurityAsset(systemId,AssetImportMapper.INSTANCE.toDTO(asset),phyEnvAssets);
            }
        });
        return repeatAsset;
    }

    private List<PwdProductBO> importPwdProductAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPwdProducts())){
            return Collections.emptyList();
        }
        List<PwdProductDTO> assetList = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.PWD_PRODUCT.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toPwdProduct)
                .collect(Collectors.toList());
        List<PwdProductBO> repeatAsset = new ArrayList<>();
        excelData.getPwdProducts().forEach(asset->{
            Optional<PwdProductDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                if(StringUtils.isBlank(asset.getIsUse())){
                    asset.setIsUse(AssetConstants.USE_TAG);
                }
                Result<String> result =  assetService.savePwdProduct(systemId, AssetImportMapper.INSTANCE.toDTO(asset));
                if(!result.isSuccess()){
                    log.warn("导入的密码产品资产信息：{}，保存失败",asset);
                }else{
                    processService.setSystemProcess(SystemProcessDTO.builder()
                            .systemId(systemId)
                            .state(SystemState.PREPARE)
                            .name(EvaluationModule.ASSET_PWD_PRODUCT.getName())
                            .finishState(FinishState.FINISH)
                            .build());
                }
            }
        });
        return repeatAsset;
    }

    private List<ServerStorageBO> importServerStorageAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getServerStorages())){
            return Collections.emptyList();
        }
        List<ServerStorageDTO> assetList = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.SERVER_STORAGE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toServerStorage)
                .collect(Collectors.toList());
        List<ServerStorageBO> repeatAsset = new ArrayList<>();
        excelData.getServerStorages().forEach(asset->{
            Optional<ServerStorageDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                if(StringUtils.isBlank(asset.getIsUse())){
                    asset.setIsUse(AssetConstants.USE_TAG);
                }
                Result<String> result =  assetService.saveServerStorage(systemId, AssetImportMapper.INSTANCE.toDTO(asset));
                if(!result.isSuccess()){
                    log.warn("导入的服务器/存储设备资产信息：{}，保存失败",asset);
                }else{
                    processService.setSystemProcess(SystemProcessDTO.builder()
                            .systemId(systemId)
                            .state(SystemState.PREPARE)
                            .name(EvaluationModule.ASSET_SERVER_STORAGE.getName())
                            .finishState(FinishState.FINISH)
                            .build());
                }
            }
        });
        return repeatAsset;
    }

    private List<NetworkSecurityBO> importNetworkSecurityAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getNetworkSecurity())){
            return Collections.emptyList();
        }
        List<NetworkSecurityDTO> assetList = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.NETWORK_SECURITY.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toNetworkSecurity)
                .collect(Collectors.toList());
        List<NetworkSecurityBO> repeatAsset = new ArrayList<>();
        excelData.getNetworkSecurity().forEach(asset->{
            Optional<NetworkSecurityDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                if(StringUtils.isBlank(asset.getIsUse())){
                    asset.setIsUse(AssetConstants.USE_TAG);
                }
                Result<String> result =  assetService.saveNetworkSecurity(systemId, AssetImportMapper.INSTANCE.toDTO(asset));
                if(!result.isSuccess()){
                    log.warn("导入的网络及安全设备资产信息：{}，保存失败",asset);
                }else{
                    processService.setSystemProcess(SystemProcessDTO.builder()
                            .systemId(systemId)
                            .state(SystemState.PREPARE)
                            .name(EvaluationModule.ASSET_NETWORK_SECURITY.getName())
                            .finishState(FinishState.FINISH)
                            .build());
                }
            }
        });
        return repeatAsset;
    }

    private List<DatabaseBO> importDatabaseAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getDatabases())){
            return Collections.emptyList();
        }
        var serverStorageAssets = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.SERVER_STORAGE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toServerStorage)
                .toList();
        var assetList = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.DATABASE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toDatabase)
                .toList();
        List<DatabaseBO> repeatAsset = new ArrayList<>();
        excelData.getDatabases().forEach(asset->{
            Optional<DatabaseDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                saveDatabaseAsset(systemId,AssetImportMapper.INSTANCE.toDTO(asset),serverStorageAssets);
            }
        });
        return repeatAsset;
    }

    private List<KeyBusinessBO> importKeyBusinessAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getKeyBusiness())){
            return Collections.emptyList();
        }
        List<ServerStorageDTO> serverStorageAssets = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.SERVER_STORAGE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toServerStorage)
                .collect(Collectors.toList());

        List<KeyBusinessDTO> assetList = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.KEY_BUSINESS.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toKeyBusiness)
                .toList();
        List<KeyBusinessBO> repeatAsset = new ArrayList<>();
        excelData.getKeyBusiness().forEach(asset->{
            Optional<KeyBusinessDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                saveKeyBusinessAsset(systemId,AssetImportMapper.INSTANCE.toDTO(asset),serverStorageAssets);
            }
        });
        return repeatAsset;
    }

    private List<SubBusinessBO> importSubBusinessAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getSubBusiness())){
            return Collections.emptyList();
        }
        List<KeyBusinessDTO> keyBusinessAssets = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.KEY_BUSINESS.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toKeyBusiness)
                .collect(Collectors.toList());

        List<SubBusinessDTO> assetList = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.SUB_BUSINESS.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toSubBusiness)
                .collect(Collectors.toList());
        List<SubBusinessBO> repeatAsset = new ArrayList<>();
        excelData.getSubBusiness().forEach(asset->{
            Optional<SubBusinessDTO> source = assetList.stream()
                    .filter(a->StringUtils.equals(a.getName(),asset.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!asset.equalsDTO(source.get())){
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            }else{
                if(StringUtils.isBlank(asset.getIsUse())){
                    asset.setIsUse(AssetConstants.USE_TAG);
                }
                saveSubBusinessAsset(systemId,AssetImportMapper.INSTANCE.toDTO(asset),keyBusinessAssets);
            }
        });
        return repeatAsset;
    }

    private List<KeyDataBO> importKeyDataAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getKeyData())){
            return Collections.emptyList();
        }
        List<KeyBusinessDTO> keyBusinessAssets = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.KEY_BUSINESS.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toKeyBusiness)
                .collect(Collectors.toList());
        List<DatabaseDTO> databaseAssets = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.DATABASE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toDatabase)
                .collect(Collectors.toList());
        List<ServerStorageDTO> serverStorageAssets = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.SERVER_STORAGE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toServerStorage)
                .collect(Collectors.toList());

        List<KeyDataDTO> sourceAssets = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.KEY_DATA.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toKeyData)
                .collect(Collectors.toList());
        List<KeyDataBO> repeatAsset = new ArrayList<>();
        excelData.getKeyData().forEach(asset -> {
            Optional<KeyDataDTO> source = sourceAssets.stream()
                    .filter(a -> StringUtils.equals(a.getData(), asset.getData())
                            && StringUtils.equals(a.getOwnedApp(), asset.getOwnedApp()))
                    .findFirst();
            if (source.isPresent()) {
                if (!asset.equalsDTO(source.get())) {
                    asset.setSource(source.get());
                    repeatAsset.add(asset);
                }
            } else {
                saveKeyDataAsset(systemId, AssetImportMapper.INSTANCE.toDTO(asset), keyBusinessAssets, databaseAssets, serverStorageAssets);
            }
        });
        return repeatAsset;
    }

    private List<SecurityDocumentBO> importSecurityDocument(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getSecurityDocuments())){
            return Collections.emptyList();
        }
        List<SecurityDocumentDTO> securityDocumentDTOS = securityDocumentService.findSecurityDocument(systemId);
        List<SecurityDocumentBO> repeatAsset = new ArrayList<>();
        excelData.getSecurityDocuments().forEach(sd->{
            Optional<SecurityDocumentDTO> source = securityDocumentDTOS.stream()
                    .filter(a->StringUtils.equals(a.getName(),sd.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!sd.equalsDTO(source.get())){
                    sd.setSource(source.get());
                    repeatAsset.add(sd);
                }
            }else{
                SecurityDocumentDTO securityDocument = AssetImportMapper.INSTANCE.toDTO(sd);
                securityDocument.setSystemId(systemId);
                Result<SecurityDocumentDTO> result =  securityDocumentService.saveSecurityDocument(securityDocument);
                if(!result.isSuccess()){
                    log.warn("导入的安全管理文档信息：{}，保存失败",sd);
                }else{
                    processService.setSystemProcess(SystemProcessDTO.builder()
                            .systemId(systemId)
                            .state(SystemState.PREPARE)
                            .name(EvaluationModule.ASSET_SECURITY_DOC.getName())
                            .finishState(FinishState.FINISH)
                            .build());
                }
            }
        });
        return repeatAsset;
    }

    private List<PersonnelBO> importPersonnel(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPersonnel())){
            return Collections.emptyList();
        }
        List<PersonnelDTO> personnelDTOS = personnelService.findPersonnel(systemId);
        List<PersonnelBO> repeatAsset = new ArrayList<>();
        excelData.getPersonnel().forEach(p->{
            Optional<PersonnelDTO> source = personnelDTOS.stream()
                    .filter(a->StringUtils.equals(a.getName(),p.getName()))
                    .findFirst();
            if(source.isPresent()){
                if(!p.equalsDTO(source.get())){
                    p.setSource(source.get());
                    repeatAsset.add(p);
                }
            }else{
                PersonnelDTO personnel = AssetImportMapper.INSTANCE.toDTO(p);
                personnel.setSystemId(systemId);
                Result<PersonnelDTO> result =  personnelService.savePersonnel(personnel);
                if(!result.isSuccess()){
                    log.warn("导入的相关人员信息：{}，保存失败",p);
                }else{
                    processService.setSystemProcess(SystemProcessDTO.builder()
                            .systemId(systemId)
                            .state(SystemState.PREPARE)
                            .name(EvaluationModule.ASSET_PERSONNEL.getName())
                            .finishState(FinishState.FINISH)
                            .build());
                }
            }
        });
        return repeatAsset;
    }

    private void savePhySecurityAsset(String systemId,PhySecurityDTO asset,List<PhyEnvDTO> phyEnvAssets){
        PhyEnvDTO relatedAsset = phyEnvAssets.stream()
                .filter(a->StringUtils.equals(a.getName(),asset.getLocation()))
                .findFirst()
                .orElse(null);
        if(Objects.nonNull(relatedAsset)){
            asset.setQuoteAssetId(relatedAsset.getId());
        }
        Result<String> result =  assetService.savePhySecurity(systemId, asset);
        if(!result.isSuccess()){
            log.warn("导入的物理安防设施资产信息：{}，保存失败",asset);
        }else{
            processService.setSystemProcess(SystemProcessDTO.builder()
                    .systemId(systemId)
                    .state(SystemState.PREPARE)
                    .name(EvaluationModule.ASSET_PHY_SECURITY.getName())
                    .finishState(FinishState.FINISH)
                    .build());
        }
    }

    private void saveDatabaseAsset(String systemId,DatabaseDTO asset,List<ServerStorageDTO> serverStorageAssets){
        if(Objects.isNull(asset.getIsUse())){
            asset.setIsUse(true);
        }
        if(StringUtils.isNotEmpty(asset.getLocation())){
            String quoteAssetId = Stream.of(StringUtils.split(asset.getLocation(),AssetConstants.KEY_BUSINESS_LOCATION_SPLIT))
                    .filter(StringUtils::isNotBlank)
                    .flatMap(name->serverStorageAssets.stream().filter(a->StringUtils.equals(a.getName(),name)))
                    .map(ServerStorageDTO::getId)
                    .collect(Collectors.joining(BaseConstants.MULTI_SPLIT_CHAR));
            asset.setQuoteAssetId(quoteAssetId);
        }
        Result<String> result =  assetService.saveDatabase(systemId, asset);
        if(!result.isSuccess()){
            log.warn("导入的数据库管理系统资产信息：{}，保存失败",asset);
        }else{
            processService.setSystemProcess(SystemProcessDTO.builder()
                    .systemId(systemId)
                    .state(SystemState.PREPARE)
                    .name(EvaluationModule.ASSET_DATABASE.getName())
                    .finishState(FinishState.FINISH)
                    .build());
        }
    }

    private void saveKeyBusinessAsset(String systemId,KeyBusinessDTO asset,List<ServerStorageDTO> serverStorageAssets){
        if(StringUtils.isNotEmpty(asset.getLocation())){
            String quoteAssetId = Stream.of(StringUtils.split(asset.getLocation(),AssetConstants.KEY_BUSINESS_LOCATION_SPLIT))
                    .filter(StringUtils::isNotBlank)
                    .flatMap(name->serverStorageAssets.stream().filter(a->StringUtils.equals(a.getName(),name)))
                    .map(ServerStorageDTO::getId)
                    .collect(Collectors.joining(BaseConstants.MULTI_SPLIT_CHAR));
            asset.setQuoteAssetId(quoteAssetId);
        }
        Result<String> result =  assetService.saveKeyBusiness(systemId, asset);
        if(!result.isSuccess()){
            log.warn("导入的关键业务应用资产信息：{}，保存失败",asset);
        }else{
            processService.setSystemProcess(SystemProcessDTO.builder()
                    .systemId(systemId)
                    .state(SystemState.PREPARE)
                    .name(EvaluationModule.ASSET_KEY_BUSINESS.getName())
                    .finishState(FinishState.FINISH)
                    .build());
        }
    }

    private void saveSubBusinessAsset(String systemId,SubBusinessDTO asset,List<KeyBusinessDTO> keyBusinessAssets){
        KeyBusinessDTO relatedKeyBusinessAsset = keyBusinessAssets.stream()
                .filter(a->StringUtils.equals(a.getName(),asset.getOwnedApp()))
                .findFirst()
                .orElse(null);
        if(Objects.nonNull(relatedKeyBusinessAsset)){
            asset.setQuoteAssetId(relatedKeyBusinessAsset.getId());
        }
        Result<String> result =  assetService.saveSubBusiness(systemId,relatedKeyBusinessAsset.getId(), asset);
        if(!result.isSuccess()){
            log.warn("导入的子对象(关键业务应用)资产信息：{}，保存失败", asset);
        } else {
            processService.setSystemProcess(SystemProcessDTO.builder()
                    .systemId(systemId)
                    .state(SystemState.PREPARE)
                    .name(AssetClassification.SUB_BUSINESS.getName())
                    .finishState(FinishState.FINISH)
                    .build());
        }
    }

    private void saveKeyDataAsset(String systemId, KeyDataDTO assetKeyData,
                                  List<KeyBusinessDTO> keyBusinessAssets,
                                  List<DatabaseDTO> databaseAssets,
                                  List<ServerStorageDTO> serverStorageAssets) {
        assetKeyData.setIsUse(true);
        KeyBusinessDTO relatedKeyBusinessAsset = keyBusinessAssets.stream()
                .filter(a -> StringUtils.equals(a.getName(), assetKeyData.getOwnedApp()))
                .findFirst()
                .orElse(null);
        if (Objects.nonNull(relatedKeyBusinessAsset)) {
            assetKeyData.setQuoteAssetId(AssetUtils.getQuoteAssetIdByKeyData(assetKeyData.getQuoteAssetId(),
                    relatedKeyBusinessAsset.getId(), AssetConstants.KEY_DATA_OWNED_APP_POSITION));
        }
        if (StringUtils.isNotBlank(assetKeyData.getLocation())) {
            DatabaseDTO relatedDatabaseAsset = databaseAssets.stream()
                    .filter(a->StringUtils.equals(a.getName(),assetKeyData.getLocation()))
                    .findFirst()
                    .orElse(null);
            if (Objects.nonNull(relatedDatabaseAsset)) {
                assetKeyData.setQuoteAssetId(AssetUtils.getQuoteAssetIdByKeyData(assetKeyData.getQuoteAssetId(),
                        relatedDatabaseAsset.getId(), AssetConstants.KEY_DATA_LOCATION_POSITION));
            } else {
                serverStorageAssets.stream()
                        .filter(a -> StringUtils.equals(a.getName(), assetKeyData.getLocation()))
                        .findFirst()
                        .ifPresent(ss -> assetKeyData.setQuoteAssetId(AssetUtils.getQuoteAssetIdByKeyData(assetKeyData.getQuoteAssetId(),
                                ss.getId(), AssetConstants.KEY_DATA_LOCATION_POSITION)));
            }
        }
        Result<String> result = assetService.saveKeyData(systemId, assetKeyData);
        if(!result.isSuccess()){
            log.warn("导入的重要数据资产信息：{}，保存失败",assetKeyData);
        }else{
            processService.setSystemProcess(SystemProcessDTO.builder()
                    .systemId(systemId)
                    .state(SystemState.PREPARE)
                    .name(EvaluationModule.ASSET_KEY_DATA.getName())
                    .finishState(FinishState.FINISH)
                    .build());
        }
    }

    private void coverPhyEnvAssets(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPhyEnvs())){
            return;
        }
        excelData.getPhyEnvs().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    PhyEnvDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    Result<String> result =  assetService.savePhyEnv(systemId, data);
                    if(!result.isSuccess()){
                        log.warn("导入的物理环境资产信息：{}，进行覆盖失败",asset);
                    }else{
                        processService.setSystemProcess(SystemProcessDTO.builder()
                                .systemId(systemId)
                                .state(SystemState.PREPARE)
                                .name(EvaluationModule.ASSET_PHY_ENV.getName())
                                .finishState(FinishState.FINISH)
                                .build());
                    }
                });
    }

    private void coverPhySecurityAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPhySecurity())){
            return;
        }
        List<PhyEnvDTO> phyEnvAssets = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.PHY_ENV.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toPhyEnvDTO)
                .collect(Collectors.toList());
        excelData.getPhySecurity().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    if(StringUtils.isBlank(asset.getIsUse())){
                        asset.setIsUse(AssetConstants.USE_TAG);
                    }
                    PhySecurityDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    savePhySecurityAsset(systemId,data,phyEnvAssets);
                });
    }

    private void coverPwdProductAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPwdProducts())){
            return;
        }
        excelData.getPwdProducts().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    if(StringUtils.isBlank(asset.getIsUse())){
                        asset.setIsUse(AssetConstants.USE_TAG);
                    }
                    PwdProductDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    Result<String> result =  assetService.savePwdProduct(systemId, data);
                    if(!result.isSuccess()){
                        log.warn("导入的密码产品资产信息：{}，进行覆盖失败",asset);
                    }else{
                        processService.setSystemProcess(SystemProcessDTO.builder()
                                .systemId(systemId)
                                .state(SystemState.PREPARE)
                                .name(EvaluationModule.ASSET_PWD_PRODUCT.getName())
                                .finishState(FinishState.FINISH)
                                .build());
                    }
                });
    }

    private void coverServerStorageAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getServerStorages())){
            return;
        }
        excelData.getServerStorages().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    if(StringUtils.isBlank(asset.getIsUse())){
                        asset.setIsUse(AssetConstants.USE_TAG);
                    }
                    ServerStorageDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    Result<String> result =  assetService.saveServerStorage(systemId, data);
                    if(!result.isSuccess()){
                        log.warn("导入的服务器/存储设备资产信息：{}，进行覆盖失败",asset);
                    }else{
                        processService.setSystemProcess(SystemProcessDTO.builder()
                                .systemId(systemId)
                                .state(SystemState.PREPARE)
                                .name(EvaluationModule.ASSET_SERVER_STORAGE.getName())
                                .finishState(FinishState.FINISH)
                                .build());
                    }
                });
    }

    private void coverNetworkSecurityAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getNetworkSecurity())){
            return;
        }
        excelData.getNetworkSecurity().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    if(StringUtils.isBlank(asset.getIsUse())){
                        asset.setIsUse(AssetConstants.USE_TAG);
                    }
                    NetworkSecurityDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    Result<String> result =  assetService.saveNetworkSecurity(systemId, data);
                    if(!result.isSuccess()){
                        log.warn("导入的网络及安全设备资产信息：{}，进行覆盖失败",asset);
                    }else{
                        processService.setSystemProcess(SystemProcessDTO.builder()
                                .systemId(systemId)
                                .state(SystemState.PREPARE)
                                .name(EvaluationModule.ASSET_NETWORK_SECURITY.getName())
                                .finishState(FinishState.FINISH)
                                .build());
                    }
                });
    }

    private void coverDatabaseAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getDatabases())){
            return;
        }
        excelData.getDatabases().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    if(StringUtils.isBlank(asset.getIsUse())){
                        asset.setIsUse(AssetConstants.USE_TAG);
                    }
                    DatabaseDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    Result<String> result =  assetService.saveDatabase(systemId, data);
                    if(!result.isSuccess()){
                        log.warn("导入的数据库管理系统资产信息：{}，进行覆盖失败",asset);
                    }else{
                        processService.setSystemProcess(SystemProcessDTO.builder()
                                .systemId(systemId)
                                .state(SystemState.PREPARE)
                                .name(EvaluationModule.ASSET_DATABASE.getName())
                                .finishState(FinishState.FINISH)
                                .build());
                    }
                });
    }

    private void coverKeyBusinessAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getKeyBusiness())){
            return;
        }
        List<ServerStorageDTO> serverStorageAssets = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.SERVER_STORAGE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toServerStorage)
                .collect(Collectors.toList());
        excelData.getKeyBusiness().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    KeyBusinessDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    saveKeyBusinessAsset(systemId,data,serverStorageAssets);
                });
    }

    private void coverSubBusinessAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getSubBusiness())){
            return;
        }
        List<KeyBusinessDTO> keyBusinessAssets = assetRepository.findAllBySystemIdAndClassId(systemId,AssetClassification.KEY_BUSINESS.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toKeyBusiness)
                .collect(Collectors.toList());
        excelData.getSubBusiness().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    if(StringUtils.isBlank(asset.getIsUse())){
                        asset.setIsUse(AssetConstants.USE_TAG);
                    }
                    SubBusinessDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    saveSubBusinessAsset(systemId,data,keyBusinessAssets);
                });
    }

    private void coverKeyDataAsset(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getKeyData())){
            return;
        }
        List<DatabaseDTO> databaseAssets = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.DATABASE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toDatabase)
                .collect(Collectors.toList());
        List<KeyBusinessDTO> keyBusinessAssets = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.KEY_BUSINESS.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toKeyBusiness)
                .collect(Collectors.toList());
        List<ServerStorageDTO> serverStorageAssets = assetRepository.findAllBySystemIdAndClassId(systemId, AssetClassification.SERVER_STORAGE.getId())
                .stream()
                .map(AssetMapper.INSTANCE::toServerStorage)
                .collect(Collectors.toList());
        excelData.getKeyData().stream()
                .filter(asset -> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset -> {
                    KeyDataDTO data = AssetImportMapper.INSTANCE.toDTO(asset);
                    data.setId(asset.getSource().getId());
                    data.setIsUse(true);
                    saveKeyDataAsset(systemId, data, keyBusinessAssets, databaseAssets, serverStorageAssets);
                });
    }

    private void coverSecurityDocument(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getSecurityDocuments())){
            return;
        }
        excelData.getSecurityDocuments().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    SecurityDocumentDTO securityDocument = AssetImportMapper.INSTANCE.toDTO(asset);
                    securityDocument.setId(asset.getSource().getId());
                    securityDocument.setSystemId(systemId);
                    Result<SecurityDocumentDTO> result =  securityDocumentService.saveSecurityDocument(securityDocument);
                    if(!result.isSuccess()){
                        log.warn("导入的安全管理文档信息：{}，进行覆盖失败",asset);
                    }else{
                        processService.setSystemProcess(SystemProcessDTO.builder()
                                .systemId(systemId)
                                .state(SystemState.PREPARE)
                                .name(EvaluationModule.ASSET_SECURITY_DOC.getName())
                                .finishState(FinishState.FINISH)
                                .build());
                    }
                });
    }

    private void coverPersonnel(String systemId,AssetExcelBO excelData){
        if(CollectionUtils.isEmpty(excelData.getPersonnel())){
            return;
        }
        excelData.getPersonnel().stream()
                .filter(asset-> (Objects.isNull(asset.getRepeatCover())
                        ? excelData.getGlobalCover()
                        : asset.getRepeatCover()))
                .forEach(asset->{
                    PersonnelDTO personnel = AssetImportMapper.INSTANCE.toDTO(asset);
                    personnel.setId(asset.getSource().getId());
                    personnel.setSystemId(systemId);
                    Result<PersonnelDTO> result =  personnelService.savePersonnel(personnel);
                    if(!result.isSuccess()){
                        log.warn("导入的相关人员信息：{}，进行覆盖失败",asset);
                    }else{
                        processService.setSystemProcess(SystemProcessDTO.builder()
                                .systemId(systemId)
                                .state(SystemState.PREPARE)
                                .name(EvaluationModule.ASSET_PERSONNEL.getName())
                                .finishState(FinishState.FINISH)
                                .build());
                    }
                });
    }

}